package com.ffcc.fitness.user.service.impl;

import com.ffcc.fitness.base.exception.ServiceException;
import com.ffcc.fitness.base.response.StatusCode;
import com.ffcc.fitness.coach.mapper.CoachMapper;
import com.ffcc.fitness.coach.pojo.entity.Coach;
import com.ffcc.fitness.coach.pojo.vo.CoachInfo;
import com.ffcc.fitness.gym.mapper.GymMapper;
import com.ffcc.fitness.gym.pojo.entity.Gym;
import com.ffcc.fitness.gym.pojo.vo.GymInfo;
import com.ffcc.fitness.merchant.mapper.MerchantMapper;
import com.ffcc.fitness.merchant.pojo.entity.Merchant;
import com.ffcc.fitness.merchant.pojo.vo.MerchantInfo;
import com.ffcc.fitness.user.mapper.UserMapper;
import com.ffcc.fitness.user.pojo.dto.UserLoginParam;
import com.ffcc.fitness.user.pojo.dto.UserSaveParam;
import com.ffcc.fitness.user.pojo.dto.UserUpdateParam;
import com.ffcc.fitness.user.pojo.entity.User;
import com.ffcc.fitness.user.pojo.vo.UserVO;
import com.ffcc.fitness.user.service.UserService;
import com.ffcc.fitness.user.service.UserSessionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Random;

@Slf4j
@Service
public class UserServiceImpl implements UserService {    @Autowired
    UserMapper userMapper;
    @Autowired
    CoachMapper coachMapper;
    @Autowired
    MerchantMapper merchantMapper;
    @Autowired
    GymMapper gymMapper;
    @Autowired
    UserSessionService userSessionService;
    @Override
    public UserVO login(UserLoginParam userLoginParam) {
        log.debug("用户登录，参数：{}", userLoginParam);
        UserVO userVO = userMapper.selectByUsername(userLoginParam.getUsername());
        log.info("用户登录，查询结果：{}", userVO);
        if (userVO == null) {
            throw new ServiceException(StatusCode.USERNAME_ERROR);
        }
        if (!userVO.getPassword().equals(userLoginParam.getPassword())) {
            throw new ServiceException(StatusCode.PASSWORD_ERROR);
        }
          // 使用会话管理服务执行登录（包含踢下线逻辑）
        cn.dev33.satoken.stp.SaTokenInfo saTokenInfo = userSessionService.loginWithKickout(userVO.getUserId());
        
        // 转换为自定义的TokenInfo结构
        com.ffcc.fitness.user.pojo.entity.TokenInfo tokenInfo = new com.ffcc.fitness.user.pojo.entity.TokenInfo();
        tokenInfo.setTokenName(saTokenInfo.getTokenName());
        tokenInfo.setTokenValue(saTokenInfo.getTokenValue());
        tokenInfo.setIsLogin(true); // 明确设置登录状态
        tokenInfo.setLoginId(String.valueOf(saTokenInfo.getLoginId()));
        tokenInfo.setLoginType(saTokenInfo.getLoginType());
        tokenInfo.setTokenTimeout(saTokenInfo.getTokenTimeout());
        tokenInfo.setSessionTimeout(saTokenInfo.getSessionTimeout());
        tokenInfo.setTokenSessionTimeout(saTokenInfo.getTokenSessionTimeout());
        tokenInfo.setTokenActiveTimeout(saTokenInfo.getTokenActiveTimeout());
        tokenInfo.setLoginDevice("web");
        
        userVO.setTokenInfo(tokenInfo);
        
        return userVO;
    }


    @Override
    public void reg(UserSaveParam userSaveParam) {
        UserVO userVO = userMapper.selectByUsername(userSaveParam.getUsername());
        if (userVO != null) {
            throw new ServiceException(StatusCode.USERNAME_ALREADY_EXISTS);
        }
        User user = new User();
        BeanUtils.copyProperties(userSaveParam, user);
        Random r = new Random();
        //1000-99999 0 98999 0 99000
        int r1 = r.nextInt(99000) + 1000;
        user.setNickname("用户" + r1);
        user.setAdminId(1L);
        user.setGender(null);
        user.setBirth(null);
        user.setEmail(null);
        user.setAvatarImgUrl(null);
        user.setAddress(null);
        userMapper.insert(user);

        // 获取刚刚插入的用户ID
        Long userId = user.getUserId();

        // 根据用户选择的角色插入对应表
        Integer role = userSaveParam.getRole();
        if (role != null) {
            switch (role) {
                case 2: // 健身教练
                    Coach coach = new Coach();
                    coach.setUserId(userId);
                    coach.setCertification(null);
                    coach.setSpecialty(null);
                    coach.setHourlyRate(BigDecimal.ZERO);
                    coach.setTeachingYears(0);
                    coach.setCoachDesc(null);
                    coach.setCreateTime(LocalDateTime.now());
                    coachMapper.insert(coach);
                    break;
                case 3: // 器械商家
                    Merchant merchant = new Merchant();
                    merchant.setUserId(userId);
                    merchant.setName(null);
                    merchant.setLicense(null);
                    merchant.setDescription(null);
                    merchantMapper.insert(merchant);
                    break;
                case 4:
                    // 场馆人员
                    // 场馆人员注册后需要去认领现有的POI场馆，不在此处创建空记录
                    // 用户可以在场馆搜索页面找到并认领自己的场馆
                    log.info("注册了一个场馆人员用户，userId: {}", userId);
                    break;
                default:

                    break;
            }
        }
    }

    @Override
    public UserVO update(UserUpdateParam userUpdateParam) {
        //接收的前端传来的参数
        log.info("修改用户信息，参数：{}", userUpdateParam);
        UserVO userVO = userMapper.selectByUsername(userUpdateParam.getUsername());
        BeanUtils.copyProperties(userUpdateParam, userVO);
        userMapper.update(userVO);
        //修改完后，把新的用户信息返回
        return userVO;
    }

    @Override
    public UserVO selectByUsername(String username) {
        // 查询用户基本信息
        UserVO userVO = userMapper.selectByUsername(username);
        // 如果是健身教练，补充教练信息
        if (userVO != null && userVO.getRole() == 2) {
            Coach coach = coachMapper.selectByUsername(username);
            log.info("coach有没有查到教练信息："+coach);
            if (coach != null) {
                userVO.setCoachInfo(new CoachInfo(coach));
            }
        }        // 如果是器械商家，补充商家信息
        if (userVO != null && userVO.getRole() == 3) {
            Merchant merchant = merchantMapper.selectByUsername(username);
            log.info("merchant有没有查到商家信息：" + merchant);
            if (merchant != null) {
                userVO.setMerchantInfo(new MerchantInfo(merchant));
            }
        }        // 如果是场馆人员，补充场馆信息（只有认领了场馆才有信息）
        if (userVO != null && userVO.getRole() == 4) {
            Gym gym = gymMapper.selectByUsername(username);
            log.info("gym有没有查到场馆信息：" + gym);
            // 只有当场馆已被认领且有完整信息时才设置gymInfo
            if (gym != null && gym.getName() != null && !"pending".equals(gym.getStatus())) {
                userVO.setGymInfo(new GymInfo(gym));
            }
        }
        log.info("select方法里，查询到的用户信息：" + userVO);
        return userVO;
    }

    @Override
    public UserVO selectByUserId(Long userId) {
        // 根据userId查询用户信息
        UserVO userVO = userMapper.selectByUserId(userId);
        if (userVO == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 获取用户角色
        Integer role = userVO.getRole();
        
        // 如果是教练角色，查询教练信息
        if (role != null && role == 2) {
            try {
                // 查询教练信息 - 转换类型
                Coach coach = coachMapper.selectByUsername(userVO.getUsername());
                if (coach != null) {
                    userVO.setCoachInfo(new CoachInfo(coach));
                }
            } catch (Exception e) {
                log.error("获取教练信息失败", e);
            }
        }
          // 如果是商家角色，查询商家信息
        if (role != null && role == 3) {
            try {
                // 查询商家信息 - 转换类型
                Merchant merchant = merchantMapper.selectByUsername(userVO.getUsername());
                if (merchant != null) {
                    userVO.setMerchantInfo(new MerchantInfo(merchant));
                }
            } catch (Exception e) {
                log.error("获取商家信息失败", e);
            }
        }
          // 如果是场馆人员角色，查询场馆信息（只有认领了场馆才有信息）
        if (role != null && role == 4) {
            try {
                // 查询场馆信息 - 转换类型
                Gym gym = gymMapper.selectByUsername(userVO.getUsername());
                // 只有当场馆已被认领且有完整信息时才设置gymInfo
                if (gym != null && gym.getName() != null && !"unclaimed".equals(gym.getStatus()) && !"pending".equals(gym.getStatus())) {
                    userVO.setGymInfo(new GymInfo(gym));
                }
            } catch (Exception e) {
                log.error("获取场馆信息失败", e);
            }
        }
        
        return userVO;
    }

}
